
package com.cn.ZhiKeDianShang.Oss;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.cn.ZhiKeDianShang.model.response.ImageBean;
import com.cn.ZhiKeDianShang.util.LogUtil;
import com.cn.ZhiKeDianShang.util.PrefShare;
import com.cn.ZhiKeDianShang.util.ToastUtil;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class OssService {

    private OSS oss;
    private String accessKeyId;
    private String bucketName;
    private String accessKeySecret;
    private String endpoint;
    private Context context;
    //但图片上传回调
    private OnUploadListener onUploadListener;
    //多图片上传 回调
    private SomeOnUploadListener someOnUploadListener;

    Context mContex;
    String orderId = "";
    int type;

    public OssService(Context context, String accessKeyId, String accessKeySecret, String endpoint, String bucketName) {
        this.context = context;
        this.endpoint = endpoint;
        this.bucketName = bucketName;
        this.accessKeyId = accessKeyId;
        this.accessKeySecret = accessKeySecret;
    }


    public void initOSSClient() {
        //OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider("<StsToken.AccessKeyId>", "<StsToken.SecretKeyId>", "<StsToken.SecurityToken>");
        //这个初始化安全性没有Sts安全，如需要很高安全性建议用OSSStsTokenCredentialProvider创建（上一行创建方式）多出的参数SecurityToken为临时授权参数
        OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(accessKeyId, accessKeySecret);
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时，默认15秒
        conf.setSocketTimeout(15 * 1000); // socket超时，默认15秒
        conf.setMaxConcurrentRequest(8); // 最大并发请求数，默认5个
        conf.setMaxErrorRetry(2); // 失败后最大重试次数，默认2次
        // oss为全局变量，endpoint是一个OSS区域地址
        oss = new OSSClient(context, endpoint, credentialProvider, conf);
    }

    /**
     * 这步操作主要是 传入回调监听   ossUpload上传代码 是递归 所以监听要放在这里
     *
     * @param urls
     * @param ossUrls
     * @param
     */
    public void ossUploadBefore(Context mContex, String orderId, final List<String> urls, final List<ImageBean> ossUrls, SomeOnUploadListener someOnUploadListener) {
        this.someOnUploadListener = someOnUploadListener;
        this.mContex = mContex;
        this.orderId = orderId;
        ossUpload(urls, ossUrls);
    }

    /**
     * 阿里云OSS上传（默认是异步多文件上传）
     *
     * @param urls
     */
    public void ossUpload(final List<String> urls, final List<ImageBean> ossUrls) {
        if (urls.size() <= 0) {
            // 文件全部上传完毕，这里编写上传结束的逻辑，如果要在主线程操作，最好用Handler或runOnUiThead做对应逻辑
            someOnUploadListener.onSuccess(ossUrls);
            return;// 这个return必须有，否则下面报越界异常，原因自己思考下哈
        }
        final String url = urls.get(0);
        if (TextUtils.isEmpty(url)) {
            urls.remove(0);
            // url为空就没必要上传了，这里做的是跳过它继续上传的逻辑。
            ossUpload(urls, ossUrls);
            return;
        }

        File file = new File(url);
        if (null == file || !file.exists()) {
            urls.remove(0);
            // 文件为空或不存在就没必要上传了，这里做的是跳过它继续上传的逻辑。
            ossUpload(urls, ossUrls);
            return;
        }
        // 文件后缀
        String fileSuffix = "";
        if (file.isFile()) {
            // 获取文件后缀名
            fileSuffix = file.getName().substring(file.getName().lastIndexOf("."));
        }
        // 文件标识符objectKey
        final String objectKey = createOssurl();
        // 下面3个参数依次为bucket名，ObjectKey名，上传文件路径
        Log.d("Debug", "上传的ossurl地址为" + objectKey);
        PutObjectRequest put = new PutObjectRequest(bucketName, objectKey, url);

        // 设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                // 进度逻辑
            }
        });
        // 异步上传
        OSSAsyncTask task = oss.asyncPutObject(put,
                new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
                    @Override
                    public void onSuccess(PutObjectRequest request, PutObjectResult result) { // 上传成功
                        LogUtil.d("UploadSucces" +endpoint + "/" +  request.getObjectKey()/*+"?x-oss-process=style/wenjianyase"*/);
//                ToastUtil.showShort("上传成功");
                        String imageUrl = request.getObjectKey();
                        ossUrls.add(new ImageBean(endpoint + "/" + imageUrl/*+"?x-oss-process=style/wenjianyase"*/, url));
                        urls.remove(0);
                        ossUpload(urls, ossUrls);// 递归同步效果

                    }

                    @Override
                    public void onFailure(PutObjectRequest request, ClientException clientExcepion,
                                          ServiceException serviceException) { // 上传失败
                        // 请求异常
                        if (clientExcepion != null) {
                            // 本地异常如网络异常等
                            clientExcepion.printStackTrace();
                        }
                        if (serviceException != null) {
                            // 服务异常
                            Log.e("ErrorCode", serviceException.getErrorCode());
                            Log.e("RequestId", serviceException.getRequestId());
                            Log.e("HostId", serviceException.getHostId());
                            Log.e("RawMessage", serviceException.getRawMessage());
                        }
                    }
                });
        // task.cancel(); // 可以取消任务
        // task.waitUntilFinished(); // 可以等待直到任务完成
    }


    /**
     * 创建oss上传地址  多图片上传之后地址（单个图片上传地址 在调用的时候传过来的）
     *
     * @return
     */
    public String createOssurl() {
        String userid = PrefShare.getInstance(mContex).getString("userId");
        String random = (int) ((Math.random() * 9 + 1) * 1000) + "";
        String url = "order/" + getTime() + "/" + userid + orderId + System.currentTimeMillis() + random+"ad";
        return url;
    }

    public String getTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date date = new Date(System.currentTimeMillis());
        String time = sdf.format(date);
        return time;
    }


    /**
     * 单张图片上传
     *
     * @param context
     * @param position
     * @param sumNumber
     * @param filename
     * @param path
     * @param onUploadListener
     */
    public void beginupload(Context context, int position, int sumNumber, String filename, final String path, OnUploadListener onUploadListener) {
        //通过填写文件名形成objectname,通过这个名字指定上传和下载的文件
        this.onUploadListener = onUploadListener;
        String objectname = filename;
        if (objectname == null || objectname.equals("")) {
            ToastUtil.showShort("文件名不能为空");
            return;
        }
        //下面3个参数依次为bucket名，Object名，上传文件路径
        PutObjectRequest put = new PutObjectRequest(bucketName, objectname, path);
        if (path == null || path.equals("")) {
            LogUtil.d("请选择图片....");
            //ToastUtils.showShort("请选择图片....");
            return;
        }
        LogUtil.d("正在上传中....");
        //ToastUtils.showShort("正在上传中....");
        // 异步上传，可以设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                LogUtil.d("currentSize: " + currentSize + " totalSize: " + totalSize);
                double progress = currentSize * 1.0 / totalSize * 100.f;
                if (onUploadListener != null) {
                    onUploadListener.onProgress(progress);
                }
            }
        });
        @SuppressWarnings("rawtypes")
        OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                LogUtil.d("UploadSucces" + endpoint + "/"+request.getObjectKey());
//                ToastUtil.showShort("上传成功");
                String imageUrl = request.getObjectKey();
                if (onUploadListener != null) {
                    LogUtil.d("到达onUploadListener里面---------");
                    onUploadListener.onSuccess(position, sumNumber, path, endpoint + "/" + imageUrl/*+"?x-oss-process=style/wenjianyase"*/);
                } else {
                    LogUtil.d("onUploadListener数据为null");
                }
            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                // 请求异常
                LogUtil.d("UploadFailure");
//                ToastUtil.showShort("UploadFailure");
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    LogUtil.e("UploadFailure：表示向OSS发送请求或解析来自OSS的响应时发生错误。\n" +
                            "  *例如，当网络不可用时，这个异常将被抛出");
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务异常
                    LogUtil.e("UploadFailure：表示在OSS服务端发生错误");
                    LogUtil.e("ErrorCode", serviceException.getErrorCode());
                    LogUtil.e("RequestId", serviceException.getRequestId());
                    LogUtil.e("HostId", serviceException.getHostId());
                    LogUtil.e("RawMessage", serviceException.getRawMessage());
                }
                onUploadListener.onFailure(1);

            }
        });
        //task.cancel(); // 可以取消任务
        //task.waitUntilFinished(); // 可以等待直到任务完成
    }

    /**
     * 单个上传图片回调
     */
    public interface OnUploadListener {
        // 上传的进度
        void onProgress(double progress);

        // 成功上传
        void onSuccess(int position, int sumNumber, String uploadPath, String imageUrl);

        // 上传失败
        void onFailure(int position);
    }

    /**
     * 多张图片上传回调
     */
    public interface SomeOnUploadListener {
        // 成功上传
        void onSuccess(final List<ImageBean> ossUrls);
    }

}

